package com.crionics.ghtable;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * The Class JGHFixedColumnTablePanel.
 */
public class JGHFixedColumnTablePanel extends JPanel {

	private static final long serialVersionUID = 1771169713409584995L;

	private int fixedColCount = 2;

	private TableModel dataModel = new EmptyTableModel();
	private JScrollPane scroll;
	private JGHTable fixedTable, mainTable;
	private FixedTableModel fixedTableModel = new FixedTableModel();
	private MainTableModel mainTableModel = new MainTableModel();

	/**
	 * The Class EmptyTableModel.
	 */
	private static class EmptyTableModel extends AbstractTableModel {

		private static final long serialVersionUID = 4299255298243518790L;

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getRowCount() {
			return 0;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getColumnCount() {
			return 0;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			return null;
		}
	}

	/**
	 * The Class MainTableModel.
	 */
	@SuppressWarnings("serial")
    private class MainTableModel extends AbstractTableModel {

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getRowCount() {
			return dataModel.getRowCount();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getColumnCount() {
			return dataModel.getColumnCount();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			return dataModel.getValueAt(rowIndex, columnIndex);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public String getColumnName(int columnIndex) {
			return dataModel.getColumnName(columnIndex);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
			dataModel.setValueAt(aValue, rowIndex, columnIndex);
		}

	}

	/**
	 * The Class FixedTableModel.
	 */
	@SuppressWarnings("serial")
    private class FixedTableModel extends MainTableModel {

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getColumnCount() {
			return getFixedColCount();
		}

	}

	/**
	 * Instantiates a new jGH fixed column table panel.
	 */
	public JGHFixedColumnTablePanel() {
		setLayout(new BorderLayout());

		fixedTable = new JGHTable(fixedTableModel);
		mainTable = new JGHTable(mainTableModel);
		//mainTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        //mainTable.setIntercellSpacing(new Dimension(0, 0));

		fixedTable.setAutoCreateColumnsFromModel(false);
		fixedTable.setSelectionModel(mainTable.getSelectionModel());

		mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		scroll = new JScrollPane(mainTable);
		Dimension d = fixedTable.getPreferredSize();
		fixedTable.setPreferredScrollableViewportSize(d);
		scroll.setRowHeaderView(fixedTable);
		scroll.setCorner(JScrollPane.UPPER_LEFT_CORNER,
				fixedTable.getTableHeader());

		add(scroll, BorderLayout.CENTER);
	}

	/**
	 * Gets the fixed col count.
	 *
	 * @return the fixed col count
	 */
	public int getFixedColCount() {
		return fixedColCount;
	}

	/**
	 * Sets the fixed col count.
	 *
	 * @param fixedColCount the new fixed col count
	 */
	public void setFixedColCount(int fixedColCount) {
		this.fixedColCount = fixedColCount;
	}

	/**
	 * Gets the fixed table.
	 *
	 * @return the fixed table
	 */
	public JGHTable getFixedTable() {
		return fixedTable;
	}

	/**
	 * Gets the main table.
	 *
	 * @return the main table
	 */
	public JGHTable getMainTable() {
		return mainTable;
	}

	/**
	 * Sets the model.
	 *
	 * @param dataModel the new model
	 */
	public void setModel(TableModel dataModel) {
		if (dataModel == null) {
			throw new IllegalArgumentException("Cannot set a null TableModel");
		}
		TableModel old = this.dataModel;
		this.dataModel = dataModel;

		mainTable.setModel(new MainTableModel());
		fixedTable.setModel(new FixedTableModel());

		mainTable.doLayout();
		TableColumnModel fixedColumnModel = fixedTable.getColumnModel();
		TableColumnModel mainColumnModel = mainTable.getColumnModel();
		for (int i = 0; i < getFixedColCount(); i++) {
			fixedColumnModel.getColumn(i).setHeaderValue(
					dataModel.getColumnName(i));
			TableColumn column = mainColumnModel.getColumn(i);
			setColumnWidth(column, 0);
		}

		setColumnWidth(fixedTable.getColumnModel().getColumn(0), 20);
		setColumnWidth(fixedTable.getColumnModel().getColumn(1), 100);

		Dimension d = scroll.getRowHeader().getPreferredSize();
		d.width = fixedTable.getColumnModel().getColumn(0).getWidth()
				+ fixedTable.getColumnModel().getColumn(1).getWidth();
		scroll.getRowHeader().setPreferredSize(d);
		scroll.getRowHeader().setBackground(Color.GRAY);
		firePropertyChange("model", old, dataModel);
	}

	/**
	 * Gets the model.
	 *
	 * @return the model
	 */
	public TableModel getModel() {
		return this.dataModel;
	}

	/**
	 * Sets the column width.
	 *
	 * @param column the column
	 * @param width the width
	 */
	private void setColumnWidth(TableColumn column, int width) {
		column.setMinWidth(width);
		column.setMaxWidth(width);
		column.setWidth(width);
	}
}
